package com.jinke.api.modules.third.easypost.util;

import com.alibaba.fastjson2.JSON;
import com.jinke.api.common.annotation.Apilog;
import com.jinke.api.common.util.CommonUtil;
import com.jinke.api.modules.app.util.MathUtil;
import com.jinke.api.modules.third.easypost.model.request.*;
import com.jinke.api.modules.third.ezeeship.model.request.EstimateRateRequest;
import com.jinke.api.modules.third.ezeeship.util.EzeeShipUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
@RequiredArgsConstructor
public class EasypostUtil {

    @Autowired
    private EzeeShipUtil ezeeShipUtil;

    public static final String TRACKING_PHP = "https://sj.tanwapost.com/xapi/tracking.php";
    public static final String CHANNEL_PHP = "https://sj.tanwapost.com/xapi/channel.php";
    public static final String SHIPMENTS = "https://api.easypost.com/v2/shipments";
    public static final String BETA_RATES = "https://api.easypost.com/beta/rates";
    public static final String ADDRESSES = "https://api.easypost.com/v2/addresses";
    public static final String PARCELS = "https://api.easypost.com/v2/parcels";
    //保险
    public static final String INSURANCES = "https://api.easypost.com/v2/insurances";
    //理电池
    public static final String CLASS_9_NEW_LITHIUM_DEVICE = "CLASS_9_NEW_LITHIUM_DEVICE";
    public static Map<String, String> accountIds;


    private String sendPostRequest(String url, String requestBody) throws IOException {
        HttpURLConnection connection = null;
        try {
            // 创建连接
            URL apiUrl = new URL(url);
            if ("true".equals(System.getenv("local"))) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 10809));
                connection = (HttpURLConnection) apiUrl.openConnection(proxy);
            } else {
                connection = (HttpURLConnection) apiUrl.openConnection();
            }


            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", "Basic RVpBS2E5Y2UxM2FhNDVhNzQ5N2JiMGI1ZTZiOGY2Y2E0Y2RiRkdGM0dnT3UwU3ZHN0VrNURHc3RKdw==");
            connection.setDoOutput(true);

            // 写入请求体
            try (OutputStream outputStream = connection.getOutputStream()) {
                outputStream.write(requestBody.getBytes("UTF-8"));
            }

            // 获取响应
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    private String sendGetRequest(String url) throws IOException {
        HttpURLConnection connection = null;
        try {
            String seq = CommonUtil.getOrderNo();
            URL apiUrl = new URL(url);
            if ("true".equals(System.getenv("local"))) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 7890));
                connection = (HttpURLConnection) apiUrl.openConnection(proxy);
            } else {
                connection = (HttpURLConnection) apiUrl.openConnection();
            }

            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", "Basic RVpBS2E5Y2UxM2FhNDVhNzQ5N2JiMGI1ZTZiOGY2Y2E0Y2RiRkdGM0dnT3UwU3ZHN0VrNURHc3RKdw==");
            // 获取响应
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                log.info("rec : {}, {}", seq, response.toString());
                return response.toString();
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }



    @Apilog(requestTypeName = "easypost-估价")
    public String getPrice(EstimateRateRequest estimateRateRequest) {
        CreateOrderRequest createOrderRequest = getCreateOrderRequest(estimateRateRequest);
        try {
            // 发送POST请求
            Map<String, Object> param = new HashMap<>();
            param.put("shipment", createOrderRequest);
            log.info("-----------EasyPost估价请求参数------------>{},{}", estimateRateRequest.getOrderNO(), JSON.toJSONString(param));
            String response = sendPostRequest(BETA_RATES, JSON.toJSONString(param));
            log.info("-----------EasyPost估价接口响应------------>{},{}", estimateRateRequest.getOrderNO(), response);
            return response;
        } catch (Exception e) {
            log.info("-----------EasyPost估价接口异常------------>{},{}", estimateRateRequest.getOrderNO(), e.getMessage());
        }
        return Strings.EMPTY;
    }

    @Apilog(requestTypeName = "easypost-下单")
    public String createOrder(EstimateRateRequest estimateRateRequest) {
        CreateOrderRequest createOrderRequest = getCreateOrderRequest(estimateRateRequest);
        try {
            // 发送POST请求
            Map<String, Object> param = new HashMap<>(1);
            param.put("shipment", createOrderRequest);
            log.info("-----------EasyPost下单请求参数---------------->{},{}", estimateRateRequest.getOrderNO(), JSON.toJSONString(param));
            String response = sendPostRequest(SHIPMENTS, JSON.toJSONString(param));
            // 处理响应
            log.info("-----------EasyPost下单响应结果: ------------>{},{}", estimateRateRequest.getOrderNO(), response);
            return response;
        } catch (Exception e) {
            log.info("-----------EasyPost下单异常: ------------>{},{}", estimateRateRequest.getOrderNO(), e.getMessage());
            e.printStackTrace();
        }
        return Strings.EMPTY;
    }

    /**
     * 本方法目前没在用
     * @param estimateRateRequest
     * @param trackingNum
     * @return
     */
    @Apilog(requestTypeName = "easypost-保险")
    public String insurances(EstimateRateRequest estimateRateRequest,String trackingNum) {
        CreateInsuranceDTO createOrderRequest = getCreateInsuranceRequest(estimateRateRequest, trackingNum) ;
        String orderNO = estimateRateRequest.getOrderNO();
        try {
            // 发送POST请求
            Map<String, Object> param = new HashMap<>(1);
            param.put("insurance", createOrderRequest);
            log.info("-----------EasyPost保险请求---------------->{},{}", orderNO, JSON.toJSONString(param));
            String response = sendPostRequest(INSURANCES, JSON.toJSONString(param));
            // 处理响应
            log.info("-----------EasyPost保险响应: ------------>{},{}", orderNO, response);
            return response;
        } catch (Exception e) {
            log.info("-----------EasyPost保险异常: ------------>{},{}", orderNO, e.getMessage());
            e.printStackTrace();
        }
        return Strings.EMPTY;
    }

    @Apilog(requestTypeName = "easypost-退保险")
    public String refundInsurances(String insuranceId,String orderNo) {
        try {
            log.info("-----------EasyPost退保险请求---------------->{},{}", orderNo, insuranceId);
            String response = sendGetRequest(INSURANCES+"/"+insuranceId+"/refund");
            // 处理响应
            log.info("-----------EasyPost退保险响应: ------------>{},{}", insuranceId, response);
            return response;
        } catch (Exception e) {
            log.info("-----------EasyPost退保险异常: ------------>{},{}", insuranceId , e.getMessage());
            e.printStackTrace();
        }
        return Strings.EMPTY;
    }

    /**
     * 创建购买保险的参数
     * @param estimateRateRequest
     * @return
     */
    private CreateInsuranceDTO getCreateInsuranceRequest(EstimateRateRequest estimateRateRequest,String trackingNum) {
        CreateInsuranceDTO dto=new CreateInsuranceDTO();


        CreateInsuranceDTO.Address sender = new CreateInsuranceDTO.Address();
        // 创建地址
        EstimateRateRequest.Address from = estimateRateRequest.getFrom();
        sender.setName(from.getPersonName());
        sender.setCountry(from.getCountryCode());
        sender.setPhone(from.getPhone());
        sender.setCity(from.getCity());
        sender.setState(from.getStateCode());
        sender.setZip(from.getZipCode());
        sender.setStreet1(from.getAddressLine1());
        sender.setStreet2(from.getAddressLine2());
        dto.setSender(sender);

        CreateInsuranceDTO.Address recipient = new CreateInsuranceDTO.Address();
        EstimateRateRequest.Address to = estimateRateRequest.getTo();
        recipient.setName(to.getPersonName());
        recipient.setCountry(to.getCountryCode());
        recipient.setPhone(to.getPhone());
        recipient.setCity(to.getCity());
        recipient.setState(to.getStateCode());
        recipient.setZip(to.getZipCode());
        recipient.setStreet1(to.getAddressLine1());
        recipient.setStreet2(to.getAddressLine2());
        recipient.setResidential(to.getIsResidential());
        dto.setRecipient(recipient);


        dto.setTracking_code(trackingNum);

        dto.setCarrier(estimateRateRequest.getCarrierCode().toUpperCase());
        //可查询此保险
        dto.setReference(estimateRateRequest.getOrderNO());
        //想投保的金额
        BigDecimal insurance = estimateRateRequest.getParcels().get(0).getInsurance();
        dto.setAmount(insurance.toString());
//dto.setMode("test");
        return dto;
    }


    @NotNull
    private CreateOrderRequest getCreateOrderRequest(EstimateRateRequest estimateRateRequest) {
        CreateOrderRequest createOrderRequest = new CreateOrderRequest();
        createOrderRequest.setCarrierAccounts(Arrays.asList(accountIds.get(estimateRateRequest.getCarrierCode())));
        createOrderRequest.setService(estimateRateRequest.getServiceCode());
        CreateOrderRequest.Address sender = new CreateOrderRequest.Address();

        // 创建地址
        EstimateRateRequest.Address from = estimateRateRequest.getFrom();
        sender.setName(from.getPersonName());
        sender.setCountry(from.getCountryCode());
        sender.setPhone(from.getPhone());
        sender.setCity(from.getCity());
        sender.setState(from.getStateCode());
        sender.setZip(from.getZipCode());
        sender.setStreet1(from.getAddressLine1());
        sender.setStreet2(from.getAddressLine2());
        createOrderRequest.setSender(sender);

        CreateOrderRequest.Address recipient = new CreateOrderRequest.Address();
        EstimateRateRequest.Address to = estimateRateRequest.getTo();
        recipient.setName(to.getPersonName());
        recipient.setCountry(to.getCountryCode());
        recipient.setPhone(to.getPhone());
        recipient.setCity(to.getCity());
        recipient.setState(to.getStateCode());
        recipient.setZip(to.getZipCode());
        recipient.setStreet1(to.getAddressLine1());
        recipient.setStreet2(to.getAddressLine2());
        recipient.setResidential(to.getIsResidential());
        createOrderRequest.setRecipient(recipient);

        // 只支持单包裹
        CreateOrderRequest.Parcel parcel = new CreateOrderRequest.Parcel();
        EstimateRateRequest.Parcel old = estimateRateRequest.getParcels().get(0);
        BigDecimal weight = BigDecimal.valueOf(Double.parseDouble(old.getWeight()));
        // 转换成镑
        if ("lb".equals(old.getMassUnit())) {
            weight = MathUtil.lb2oz(weight);
        }
        if ("kg".equals(old.getMassUnit())) {
            weight = MathUtil.kg2oz(weight);
        }
        parcel.setWeight(weight.toString());

        // 转换成in
        BigDecimal length = BigDecimal.valueOf(Double.parseDouble(old.getLength()));
        BigDecimal width = BigDecimal.valueOf(Double.parseDouble(old.getWidth()));
        BigDecimal height = BigDecimal.valueOf(Double.parseDouble(old.getHeight()));
        if ("cm".equals(old.getDistanceUnit())) {
            length = MathUtil.cm2in(length);
            width = MathUtil.cm2in(width);
            height = MathUtil.cm2in(height);
        }

        parcel.setLength(length.toString());
        parcel.setWidth(width.toString());
        parcel.setHeight(height.toString());

        createOrderRequest.setParcel(parcel);


        EstimateRateRequest.LabelExtra extra = estimateRateRequest.getExtra();

        if (extra != null) {

            CreateOrderRequest.Options options = new CreateOrderRequest.Options();
            options.setPrint_custom_1(extra.getReference());
            options.setPrint_custom_2(extra.getReference2());
            Integer batteryType = estimateRateRequest.getExtra().getBatteryType();
            if (batteryType!=null&&batteryType != 0) {
                options.setHazmat(CLASS_9_NEW_LITHIUM_DEVICE);
            }
            createOrderRequest.setOptions(options);

        }

        if (old.getIsInsured()!=null&&old.getInsurance()!=null) {
            createOrderRequest.setInsurance(old.getInsurance() + "");
        }

        return createOrderRequest;
    }

    private String addresses(CreateOrderRequest.Address address) {

        try {
            Map<String, Object> param = new HashMap<>();
            param.put("address", address);
            return sendPostRequest(ADDRESSES, JSON.toJSONString(param));

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    private String parcels(CreateOrderRequest.Parcel parcel) {

        try {
            Map<String, Object> param = new HashMap<>();
            param.put("parcel", parcel);
            return sendPostRequest(PARCELS, JSON.toJSONString(param));

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public String getLabels(GetLabelsRequest request) {
        // 设置API端点URL
        String platformNo = request.getPlatformNo();
        String apiUrl = "https://api.easypost.com/v2/shipments/" + platformNo + "/label?file_format=PDF";

        try {
            log.info("-----------EasyPost获取面单请求--------------platformNo-->{}", platformNo);
            // 发送POST请求
            String response = sendGetRequest(apiUrl);
            log.info("-----------EasyPost获取面单响应---------------platformNo->{},{}", platformNo, response);

            return response;
        } catch (IOException e) {
            log.info("-----------EasyPost获取面单异常---------------platformNo->{},{}", platformNo, e.getMessage());

        }
        return Strings.EMPTY;
    }


    @Apilog(requestTypeName = "easypost-取消")
    public String cancelLabel(String objectId,String orderNo) {
        String apiUrl = "https://api.easypost.com/v2/shipments/" + objectId + "/refund";

        CancelRequest request = new CancelRequest();
        request.setPlatformNo(objectId);

        try {
            log.info("-----------EasyPost取消请求-------------{}--objectId->{}",orderNo, objectId);

            String response = sendGetRequest(apiUrl);
            log.info("-----------EasyPost取消响应--------------{}--objectId>{},{}", orderNo,objectId, response);

            return response;
        } catch (IOException e) {
            log.info("-----------EasyPost取消异常-------------{}--objectId->{},{}",orderNo, objectId, e.getMessage());

        }
        return Strings.EMPTY;
    }

    public String tracking(String tracingNo) {

        TrackingRequest request = new TrackingRequest();
        request.setTrackingno(tracingNo);
        request.setApikey("tw_4838");
        String requestBody = JSON.toJSONString(request);

        try {
            log.info("-----------EasyPost跟踪请求---------------tracingNo->{}", tracingNo);

            // 发送POST请求
            String response = sendPostRequest(TRACKING_PHP, requestBody);
            log.info("-----------EasyPost跟踪响应----------------tracingNo>{},{}", tracingNo, response);

            return response;
        } catch (IOException e) {
            log.info("-----------EasyPost跟踪异常---------------tracingNo->{},{}", tracingNo, e.getMessage());
        }
        return Strings.EMPTY;
    }

    public String getChannel() {
        // 将OrderRequest对象转换为JSON字符串
        // 创建OrderRequest对象
        BaseEntity orderRequest = new BaseEntity();

// 设置属性值
        orderRequest.setApikey("tw_4838");

        String requestBody = JSON.toJSONString(orderRequest);

        try {
            log.info("-----------EasyPost获取渠道请求---------------}");

            // 发送POST请求
            String response = sendPostRequest(CHANNEL_PHP, requestBody);
            log.info("-----------EasyPost获取渠道响应----------------,{}",  response);
            return response;
        } catch (IOException e) {
            log.info("-----------EasyPost获取渠道异常--------------{}",  e.getMessage());

        }
        return "";
    }


}
